package com.yanqu.road.server.manager.banquet;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.dao.impl.cross.party.CrossPartyRelationDaoImpl;
import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.banquet.*;
import com.yanqu.road.entity.banquet.cross.CrossBanquetData;
import com.yanqu.road.entity.banquet.cross.CrossBanquetMember;
import com.yanqu.road.entity.banquet.invitation.CrossPartyRelationData;
import com.yanqu.road.entity.banquet.invitation.CrossUserPartyJoin;
import com.yanqu.road.entity.enums.eBanquetInfoType;
import com.yanqu.road.entity.enums.eBanquetType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.crossbanquet.CrossPartyBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.banquet.BanquetProto;
import com.yanqu.road.pb.banquet.CrossBanquetProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.CrossMarriageGroupMgr;
import com.yanqu.road.server.pb.banquet.CrossBanquetPb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ListHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static com.yanqu.road.server.manager.banquet.CrossBanquetMgr.initRobotUserInfo;

/**
 * 用来做跨服宴会，目前只支持最普通的私宴
 */
public class CrossPartyMgr extends TempMgr {
    private static Map<String, CrossBanquetData> partyMap;
    private static Map<Long, Map<String, CrossBanquetData>> serverPartyMap;

    private static Map<String, Map<Long, CrossBanquetMember>> partyMemberMap = new ConcurrentHashMap<>();

    private static RandomHelper random = new RandomHelper();

    //用户的互宴信息
    private static Map<Long, List<CrossUserPartyJoin>> partyJoinMap = new ConcurrentHashMap<>();

    private static Map<Long, List<CrossUserPartyJoin>> openPartyJoinMap = new ConcurrentHashMap<>();
    private static Map<Long, List<CrossUserPartyJoin>> joinPartyJoinMap = new ConcurrentHashMap<>();

    //      宴会类型     较小的userId  较大的 userId
    private static Map<Integer, Map<Long, List<CrossPartyRelationData>>> partyRelationshipMap = new ConcurrentHashMap<>();

    private static Set<CrossPartyRelationData> needUpdateRelationDataLSet = new HashSet<>();

    private static Map<Long, List<BanquetProto.AddBanquetRelationshipMsg>> needSyncrelationShipMap = new ConcurrentHashMap<>();

    private static Map<Long, Integer> ackRelationshipMap = new ConcurrentHashMap<>();

    private static Set<Long> needSyncFeastServerSet = new HashSet<>();

    private static Map<String, List<CrossBanquetMember>> needSyncPartyMemberMap = new ConcurrentHashMap<>();

    /**
     * 开启宴会
     *
     * @param serverId
     * @param userId
     * @param userBaseInfo
     * @param type
     * @return
     */
    public static BanquetProto.CrossOpenPartyRespMsg.Builder openParty(long serverId, long userId, UserBaseInfo userBaseInfo, int type, String invitationId, String invitationInfo, String serverListStr, String giftTypeAccept) {
        BanquetProto.CrossOpenPartyRespMsg.Builder resp = BanquetProto.CrossOpenPartyRespMsg.newBuilder();
        resp.setRet(0);
        resp.setInvitationId(invitationId);
        resp.setType(type);
        synchronized (partyMap) {
            CrossUserMgr.updateUserBaseInfo(userId, userBaseInfo);
            if (!canOpenBanquet(serverId, userId, type)) {
                //同时只能开一个哦
                return resp.setRet(GameErrorCode.E_BANQUET_ONLY_ONE);
            }
            if (CrossBanquetConfigMgr.isServerNormalBanquet(type)) {
                List<Long> partyServerList = CrossMarriageGroupMgr.getPartyServerList(serverId);
                serverListStr = StringUtils.listToString(partyServerList, ",");
            } else if (CrossBanquetConfigMgr.isServerFeastBanquet(type)) {
                List<Long> partyServerList = CrossMarriageGroupMgr.getFeastPartyServerList(serverId);
                serverListStr = StringUtils.listToString(partyServerList, ",");
            }
            BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(type);
            CrossBanquetData userBanquetData = new CrossBanquetData();
            userBanquetData.setBanquetId(UUIDHelper.randomUUID(String.valueOf(serverId)));
            userBanquetData.setUserId(userId);
            userBanquetData.setServerId((int) serverId);
            userBanquetData.setOpenTime(System.currentTimeMillis());
            userBanquetData.setOverTime(System.currentTimeMillis() + banquetInfo.getBanquetTime() * 1000);
            if(type == eBanquetInfoType.CrossMogulBirthdayBanquet.getValue()){
                userBanquetData.setOverTime(DateHelper.getTodayZeroTimeStamp() + DateHelper.DAY_MILLIONS);
            }
            userBanquetData.setInvitationId(invitationId);
            userBanquetData.setSendReward(false);
            userBanquetData.setType(type);
            userBanquetData.setPopularity(0);
            userBanquetData.setIntegral(0);
            userBanquetData.setUserCount(0);
            userBanquetData.setStatus(1);
            userBanquetData.setInvitationInfo(invitationInfo);
            userBanquetData.setUserBaseInfo(userBaseInfo);
            userBanquetData.setServerListStr(serverListStr);
            userBanquetData.setGiftTypeAccept(giftTypeAccept);
            userBanquetData.setInsertOption();
            partyMap.put(userBanquetData.getBanquetId(), userBanquetData);
            addToServerPartyMap(serverId, userBanquetData);
            partyMemberMap.put(userBanquetData.getBanquetId(), new ConcurrentHashMap<>());
            resp.setBanquetId(userBanquetData.getBanquetId());
            if (CrossBanquetConfigMgr.isServerFeastBanquet(userBanquetData.getType())) {
                syncCrossFeastParty(serverId);
                syncBanquetFeast(userBanquetData);
            }
            syncSelfParty(serverId, userId, null);
            if (CrossBanquetConfigMgr.isServerFeastBanquet(type)) {
                notifyPartyOpen(CrossMarriageGroupMgr.getFeastPartyServerList(serverId), userId, userBaseInfo, userBanquetData);
            } else {
                notifyPartyOpen(Collections.singletonList(serverId), userId, userBaseInfo, userBanquetData);
            }
        }
        return resp;
    }

    private static void notifyPartyOpen(List<Long> serverIdList, long userId, UserBaseInfo userBaseInfo, CrossBanquetData userBanquetData) {
        try {
            String SEPARATOR = "&#!";
            String value = "";
            Object[] arr = new Object[]{userBaseInfo.getCity(), userBaseInfo.getTitleId(), userBaseInfo.getNickName(), userBanquetData.getType(), userBanquetData.getBanquetId()};
            StringBuilder content = new StringBuilder();
            if (arr != null) {
                for (Object str : arr) {
                    content.append(str).append(SEPARATOR);
                }
            }
            if (content.length() > 0) {
                value = content.substring(0, content.length() - SEPARATOR.length());
            }
            WorldMessageProto.WorldMessageTempMsg.Builder msg = WorldMessageProto.WorldMessageTempMsg.newBuilder();
            msg.setType(13);
            msg.setSendTime(System.currentTimeMillis() / 1000);
            msg.setContent(value);
            msg.setUserId(userId);
            PlayerProto.PlayerBaseTempMsg.Builder baseMsg = PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo);
            msg.setPlayerBaseData(baseMsg);
            YanQuMessage mess = YanQuMessageUtils.buildMessage(Protocol.A_WORLD_MESSAGE_TRANSFER, msg);
            for (Long serverId : serverIdList) {
                MessageHelper.sendPacket(serverId, userId, mess);
            }
        } catch (Exception e) {
        }
    }

    private static void addToServerPartyMap(long serverId, CrossBanquetData userBanquetData) {
        synchronized (serverPartyMap) {
            Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
            if (dataMap == null) {
                dataMap = new ConcurrentHashMap<>();
                serverPartyMap.put(serverId, dataMap);
            }
            dataMap.put(userBanquetData.getBanquetId(), userBanquetData);
        }
    }


    private static void syncBanquetFeast(CrossBanquetData userBanquetData) {
        List<Long> serverList = CrossMarriageGroupMgr.getFeastPartyServerList(userBanquetData.getServerId());
        for (Long serverId : serverList) {
            BanquetProto.BanquetFeastSync.Builder msg = CrossBanquetPb.parseBanquetFeastListRespMsg(getBanquetFeast(CrossMarriageGroupMgr.getFeastPartyServerList(userBanquetData.getServerId())));
            YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_PARTY_SYNC, msg);
            MessageHelper.sendPacket(serverId, 0, message);
        }
    }

    public static List<CrossBanquetData> getBanquetFeast(Collection<Long> serverIdList) {
        List<CrossBanquetData> list = new ArrayList<>();
        for (Long serverId : serverIdList) {
            Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
            if (dataMap == null) {
                continue;
            }
            for (CrossBanquetData data : new ArrayList<>(dataMap.values())) {
                if (!isBanquetOver(data.getBanquetId()) && CrossBanquetConfigMgr.isServerFeastBanquet(data.getType())) {
                    if (data.getServerId() == serverId) {
                        list.add(data);
                    }
                }
            }
        }
        return list;
    }

    /**
     * 是否能开启宴会
     *
     * @param userId
     * @param type
     * @return
     */
    private static boolean canOpenBanquet(long serverId, long userId, int type) {
        Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
        if (dataMap == null) {
            return true;
        }
        List<CrossBanquetData> banquetList = new ArrayList<>(dataMap.values());
        for (CrossBanquetData data : banquetList) {
            if (!isBanquetOver(data.getBanquetId()) && data.getUserId() == userId && CrossBanquetConfigMgr.isTheSameType(data.getType(), type)) {
                return false;
            }
        }
        return true;
    }

    public static boolean isBanquetOver(String banquetId) {
        CrossBanquetData userBanquetData = partyMap.get(banquetId);
        if (userBanquetData == null) {
            return true;
        }
        if (userBanquetData.getOverTime() < System.currentTimeMillis()) {
            return true;
        }
        BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
        if (banquetInfo == null) {
            return true;
        }
        if (banquetInfo.getSeat() != 0 && userBanquetData.getUserCount() >= banquetInfo.getSeat()) {
            return true;
        }
        return false;
    }

    /**
     * 加入宴会
     *
     * @param partyId
     * @param serverId
     * @param userId
     * @param userBaseInfo
     * @param giftId
     * @return
     */
    public static BanquetProto.CrossJoinPartyRespMsg.Builder joinParty(String partyId, long serverId, long userId, UserBaseInfo userBaseInfo,
                                                                       int giftId, long popularity, long integral, int giftAcceptState) {
        BanquetProto.CrossJoinPartyRespMsg.Builder respMsg = BanquetProto.CrossJoinPartyRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setGiftId(giftId);
        respMsg.setConsume("");

        CrossBanquetData party = partyMap.get(partyId);
        if (party == null) {
            return respMsg.setRet(GameErrorCode.E_BANQUET_IS_OVER);
        }
        if (CrossBanquetConfigMgr.isServerNormalBanquet(party.getType())) {
            if (party.getUserId() == userId) {//不能加自己的宴会
                return respMsg.setRet(GameErrorCode.E_BANQUET_HAS_JOIN);
            }
        }
        if (isBanquetOver(partyId)) {
            return respMsg.setRet(GameErrorCode.E_BANQUET_IS_OVER);
        }
        if (!canJoinServerParty(serverId, party.getServerId(), party.getType())) {
            return respMsg.setRet(GameErrorCode.E_BANQUET_IS_OVER);
        }
        BanquetGiftInfo banquetGiftInfo = CrossBanquetConfigMgr.getBanquetGiftInfo(party.getType(), giftId);
        if (banquetGiftInfo == null) {
            return respMsg.setRet(GameErrorCode.E_BANQUET_GIFT_ERROR);
        }
        if (!party.isGiftIdAccept(giftId)) {
            return respMsg.setRet(GameErrorCode.E_BANQUET_JOIN_GIFTTYPE_NO_ENOUGH).setGiftTypeAccept(party.getGiftTypeAccept());
        } else if (2 == giftAcceptState) {//客户端是不接受,服务端是接受
            return respMsg.setRet(GameErrorCode.E_BANQUET_JOIN_GIFTTYPE_NO_ENOUGH).setGiftTypeAccept(party.getGiftTypeAccept());
        }
        Map<Long, CrossBanquetMember> memberMap = getPartyMemberMap(partyId);
        BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(party.getType());
        CrossBanquetMember userBanquetMember = new CrossBanquetMember();
        boolean isFull = false;
        synchronized (party) {
            if (memberMap.size() >= banquetInfo.getSeat() && banquetInfo.getSeat() != 0) {
                return respMsg.setRet(GameErrorCode.E_BANQUET_MAX_SEAT);
            }
            if (memberMap.containsKey(userId)) {
                return respMsg.setRet(GameErrorCode.E_BANQUET_HAS_JOIN);
            }
            userBanquetMember.setBanquetId(partyId);
            userBanquetMember.setUserId(userId);
            userBanquetMember.setGiftId(giftId);
            userBanquetMember.setRobot(false);
            userBanquetMember.setRobotProcessId(0);
            userBanquetMember.setRobotId(0);
            userBanquetMember.setPos(memberMap.size() + 1);
            userBanquetMember.setPopularity(0);
            userBanquetMember.setIntegral(0);
            userBanquetMember.setUserBaseInfo(userBaseInfo);
            userBanquetMember.setJoinTime(System.currentTimeMillis());

            userBanquetMember.setPopularity(popularity);
            userBanquetMember.setIntegral(integral);
            userBanquetMember.setInsertOption();
            memberMap.put(userBanquetMember.getUserId(), userBanquetMember);

            respMsg.setPos(userBanquetMember.getPos());
            respMsg.setPopularity(popularity);
            respMsg.setIntegral(integral);

            party.setUserCount(memberMap.size());
            //普通的本服宴会是所有人的积分加起来
            if (CrossBanquetConfigMgr.isServerNormalBanquet(party.getType())) {
                //宴会加上人气和积分
                party.setPopularity(party.getPopularity() + popularity);
                party.setIntegral(party.getIntegral() + integral);
            }
            isFull = memberMap.size() >= banquetInfo.getSeat();
        }

        if (isFull) {
            // 如果满座了 发送幸运奖励吧
            sendLuckUserReward(banquetInfo, party, memberMap);
        }
        // 下面属于同步 放在锁内部会影响执行时间 可以异步发送
        if (CrossBanquetConfigMgr.isServerFeastBanquet(party.getType())) {
            // 这个也走定时吧
            synchronized (needSyncFeastServerSet) {
                needSyncFeastServerSet.add(serverId);
            }
        }

        if (CrossBanquetConfigMgr.isServerNormalBanquet(party.getType())) {
            addPartyRelationship(party.getUserId(), userId, userBaseInfo, party.getUserBaseInfo(), party.getType(), 0);
        }

        syncBanquetUser(party, userBanquetMember);

        return respMsg;
    }

    public static void timeSyncFeastServerParty() {
        HashSet<Long> serverIds;
        synchronized (needSyncFeastServerSet) {
            serverIds = new HashSet<>(needSyncFeastServerSet);
            needSyncFeastServerSet.clear();
        }
        if (serverIds.size() > 0) {
            for (Long serverId : serverIds) {
                syncCrossFeastParty(serverId);
            }
        }


        Map<String, List<CrossBanquetMember>> tempMap;
        synchronized (needSyncPartyMemberMap) {
            tempMap = new HashMap<>(needSyncPartyMemberMap);
            needSyncPartyMemberMap.clear();
        }
        for (Map.Entry<String, List<CrossBanquetMember>> memberEntry : tempMap.entrySet()) {
            String id = memberEntry.getKey();
            CrossBanquetData userBanquetData = partyMap.get(id);
            if (userBanquetData == null) {
                continue;
            }
            for (CrossBanquetMember userBanquetMember : memberEntry.getValue()) {
                BanquetProto.BanquetMemberSync.Builder msg = CrossBanquetPb.parseBanquetMemberSyncResp(userBanquetData, userBanquetMember, getBanquetMemberCount(userBanquetData.getBanquetId()));
                Map<Long, Set<Long>> sceneUserMap = userBanquetData.getSceneUserMap();
                for (Map.Entry<Long, Set<Long>> entry : new HashMap<>(sceneUserMap).entrySet()) {
                    Long serverId = entry.getKey();
                    Set<Long> value = entry.getValue();
                    if (value.size() > 0) {
                        BanquetProto.CrossPartyNoticeAllMsg.Builder syncMsg = BanquetProto.CrossPartyNoticeAllMsg.newBuilder();
                        syncMsg.addAllUserId(value);
                        syncMsg.setMsg(msg);
                        YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.S_CROSS_PARTY_JOIN_NOTICE_ALL, syncMsg);
                        MessageHelper.sendPacket(serverId, 0, message);
                    }
                }
                syncSelfParty(userBanquetData.getUserBaseInfo().getServerId(), userBanquetData.getUserId(), userBanquetData);
                //本服宴会要通知
                if (CrossBanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())) {
                    syncJoinNoticeOwner(userBanquetData.getServerId(), userBanquetData.getUserId(), userBanquetMember);
                }
            }
        }


    }


    public static boolean canJoinServerParty(long myServerId, long ownerServerId, int type) {
        List<Long> serverList = new ArrayList<>();
        if (CrossBanquetConfigMgr.isServerNormalBanquet(type)) {
            serverList = CrossMarriageGroupMgr.getPartyServerList(myServerId);
        } else if (CrossBanquetConfigMgr.isServerFeastBanquet(type)) {
            serverList = CrossMarriageGroupMgr.getFeastPartyServerList(myServerId);
        }

        return serverList.contains(ownerServerId);
    }


    public static void syncBanquetUser(CrossBanquetData userBanquetData, CrossBanquetMember userBanquetMember) {
        String partyId = userBanquetData.getBanquetId();
        synchronized (needSyncPartyMemberMap) {
            List<CrossBanquetMember> memberList = needSyncPartyMemberMap.get(partyId);
            if (memberList == null) {
                memberList = new ArrayList<>();
                needSyncPartyMemberMap.put(partyId, memberList);
            }
            memberList.add(userBanquetMember);
        }
    }

    //通知开宴会者有人来参加了
    public static void syncJoinNoticeOwner(long serverId, long userId, CrossBanquetMember userBanquetMember) {
        //机器人不发
        if (!userBanquetMember.isRobot()) {
            YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_JOIN_NOTICE_OWNER, CrossBanquetPb.parseBanquetJoinNoticeOwnerMsg(userBanquetMember));
            MessageHelper.sendPacket(serverId, userId, message);
        }
    }

    public static Map<Long, CrossBanquetMember> getPartyMemberMap(String partyId) {
        Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(partyId);
        if (memberMap == null) {
            synchronized (partyMemberMap) {
                memberMap = partyMemberMap.get(partyId);
                if (memberMap == null) {
                    memberMap = new ConcurrentHashMap<>();
                    partyMemberMap.put(partyId, memberMap);
                }
            }
        }
        return memberMap;
    }

    public static void addPartyRelationship(long ownerUserId, long joinUserId, UserBaseInfo joinUserBaseInfo, UserBaseInfo owenrBaseInfo, int banquetType, long beginShowTime) {
      /*  CrossUserMgr.updateUserBaseInfo(joinUserId, joinUserBaseInfo);
        int partyType = 1;
        if (banquetType == 0 || CrossBanquetConfigMgr.isServerNormalBanquet(banquetType)) {
            partyType = 1;
        } else if (CrossBanquetConfigMgr.isCrossUserBanquet(banquetType)) {
            partyType = 2;
        } else {
            return;
        }
        Map<Long, List<CrossPartyRelationData>> relationMap = partyRelationshipMap.get(partyType);
        if (relationMap == null) {
            relationMap = new ConcurrentHashMap<>();
            partyRelationshipMap.put(partyType, relationMap);
        }
        long minUserId = Math.min(ownerUserId, joinUserId);
        long maxUserId = Math.max(ownerUserId, joinUserId);

        List<CrossPartyRelationData> dataMap = relationMap.get(minUserId);
        if (dataMap == null) {
            dataMap = new ArrayList<>();
            relationMap.put(minUserId, dataMap);
        }
        CrossPartyRelationData data = null;
        for (CrossPartyRelationData relationData : dataMap) {
            if (relationData.getUserId2() == maxUserId) {
                data = relationData;
                break;
            }
        }
        if (data == null) {
            data = new CrossPartyRelationData();
            data.setUserId1(minUserId);
            data.setUserId2(maxUserId);
            data.setPartyType(partyType);
            data.setInsertOption();
            dataMap.add(data);

            List<CrossPartyRelationData> partyRelationDataMap = relationMap.get(maxUserId);
            if (partyRelationDataMap == null) {
                partyRelationDataMap = new ArrayList<>();
                relationMap.put(maxUserId, partyRelationDataMap);
            }
            partyRelationDataMap.add(data);
        }
        long lastJoinTime = data.getLastJoinTime();
        if (lastJoinTime < beginShowTime) {
            data.setJoinTimes1(0);
            data.setJoinTimes2(0);
        }
        data.setLastJoinTime(System.currentTimeMillis());
        if (data.getUserId1() == joinUserId) {
            data.setJoinTimes1(data.getJoinTimes1() + 1);
        } else {
            data.setJoinTimes2(data.getJoinTimes2() + 1);
        }
        synchronized (needUpdateRelationDataLSet) {
            needUpdateRelationDataLSet.add(data);
        }*/

        // 新逻辑 同步到跨服
        //同步加入者
        addToSyncRelationMap(joinUserBaseInfo.getServerId(), joinUserId, ownerUserId, owenrBaseInfo, banquetType, beginShowTime, true);

        //同步开宴者
        addToSyncRelationMap(owenrBaseInfo.getServerId(), ownerUserId, joinUserId, joinUserBaseInfo, banquetType, beginShowTime, false);

    }

    private static void addToSyncRelationMap(long serverId, long myUserId, long otherUserId, UserBaseInfo otherUserBaseInfo, int banquetType, long beginShowTime, boolean isMyJoin) {
        synchronized (needSyncrelationShipMap) {
            BanquetProto.AddBanquetRelationshipMsg.Builder msg = BanquetProto.AddBanquetRelationshipMsg.newBuilder();
            msg.setMyUserId(myUserId);
            msg.setOtherUserId(otherUserId);
            msg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(otherUserBaseInfo));
            msg.setBanquetType(banquetType);
            msg.setBeginShowTime(beginShowTime);
            msg.setIsMyJoin(isMyJoin);
            if (!needSyncrelationShipMap.containsKey(serverId)) {
                needSyncrelationShipMap.put(serverId, new ArrayList<>());
            }
            List<BanquetProto.AddBanquetRelationshipMsg> list = needSyncrelationShipMap.get(serverId);
            list.add(msg.build());
        }
    }

    public static void syncRelationshipToServer() {
        Map<Long, List<BanquetProto.AddBanquetRelationshipMsg>> syncMap;
        synchronized (needSyncrelationShipMap) {
            syncMap = new HashMap<>(needSyncrelationShipMap);
            needSyncrelationShipMap.clear();
        }
        for (Map.Entry<Long, List<BanquetProto.AddBanquetRelationshipMsg>> entry : syncMap.entrySet()) {
            List<BanquetProto.AddBanquetRelationshipMsg> list = entry.getValue();
            if (list.size() > 0) {
                Long serverId = entry.getKey();
                BanquetProto.SyncAddBanquetRelationshipMsg.Builder msg = BanquetProto.SyncAddBanquetRelationshipMsg.newBuilder();
                msg.addAllData(list);
                YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_RELATIONSHIP, msg);
                MessageHelper.sendPacket(serverId, 0, message);
            }
            list.clear();
        }
    }

    /**
     * 给幸运儿发送奖励吧
     *
     * @param banquetInfo
     * @param party
     * @param memberMap
     */
    private static void sendLuckUserReward(BanquetInfo banquetInfo, CrossBanquetData party, Map<Long, CrossBanquetMember> memberMap) {
        if (!"0".equals(banquetInfo.getLockReward())) {
            CrossBanquetMember memberInfo = getLuckMember(memberMap);
            if (memberInfo == null) {
                return;
            }
            // 给幸运儿发消息吧
            BanquetProto.CrossPatrySendLuckRewardMsg.Builder msg = BanquetProto.CrossPatrySendLuckRewardMsg.newBuilder();
            msg.setNickName(party.getUserBaseInfo().getNickName());
            msg.setOwnerServerId(party.getServerId());
            msg.setPartyType(party.getType());
            msg.setUserId(memberInfo.getUserId());
            List<Long> partyServerList = CrossMarriageGroupMgr.getPartyServerList(memberInfo.getUserBaseInfo().getServerId());
            if (partyServerList.size() > 1) {
                msg.setIsKuafu(true);
            } else {
                msg.setIsKuafu(false);
            }
            YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_PARTY_SEND_LUCKY_REWARD, msg);
            MessageHelper.sendPacket(memberInfo.getUserBaseInfo().getServerId(), memberInfo.getUserId(), message);
        }
    }

    //获取满座幸运者
    private static CrossBanquetMember getLuckMember(Map<Long, CrossBanquetMember> memberMap) {
        Map<Long, CrossBanquetMember> userMap = new ConcurrentHashMap<>();
        long i = 1;
        for (CrossBanquetMember member : memberMap.values()) {
            if (!member.isRobot()) {
                userMap.put(i++, member);
            }
        }
        long randomLuckPos = random.next(1, userMap.size() + 1);
        return userMap.get(randomLuckPos);
    }

    /**
     * @param serverId
     * @param userId
     * @param partyId
     * @return
     */
    public static int getReward(long serverId, long userId, String partyId) {
        return 0;
    }

    /**
     * 同步加入
     *
     * @param partyId
     */
    public static void syncJoin(String partyId) {

    }

    public static void syncOpen() {

    }

    /**
     * 获取宴会列表
     *
     * @param serverId
     * @param type         1.本服 2跨服
     * @param relativeList
     * @param serverList
     * @return
     */
    public static Map<String, CrossBanquetData> getPartyList(long serverId, long userId, int type, Set<Long> relativeList, Collection<Long> serverList) {
        int count = 0;
        Map<String, CrossBanquetData> banquetMap = new ConcurrentHashMap<>();
        List<CrossBanquetData> banquetList = getPartyListByServerId(serverList);
        banquetList.sort((o1, o2) -> {
            long userId1 = o1.getUserId();
            long userId2 = o2.getUserId();
            int value = 0;
            if (relativeList.contains(userId1)) {
                value--;
            }
            if (relativeList.contains(userId2)) {
                value++;
            }
            if (value != 0) {
                return value;
            }
            int serverId1 = o1.getServerId();
            int serverId2 = o2.getServerId();
            if (serverId == serverId1) {
                value--;
            }
            if (serverId == serverId2) {
                value++;
            }
            if (value != 0) {
                return value;
            }
            if (o1.getOverTime() == o2.getOverTime()) {
                return 0;
            }
            if (o1.getOverTime() >= o2.getOverTime()) {
                return 1;
            }
            return -1;
        });
        for (CrossBanquetData data : banquetList) {
            if (!serverList.contains(data.getUserBaseInfo().getServerId())) {
                continue;
            }
            if (!isBanquetOver(data.getBanquetId()) && data.getUserId() != userId && isBanquetType(data.getType(), type)) {
                banquetMap.put(data.getBanquetId(), data);
                count++;
            }
            if (count >= GameConfig.BANQUET_LIST_MAX) {
                break;
            }
        }
        return banquetMap;
    }

    public static List<CrossBanquetData> getPartyListByServerId(Collection<Long> serverIdList) {
        List<CrossBanquetData> list = new ArrayList<>();
        for (Long serverId : serverIdList) {
            Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
            if (dataMap != null) {
                list.addAll(dataMap.values());
            }
        }
        return list;
    }


    public static boolean isBanquetType(int banquetInfoId, int banquetType) {
        if (eBanquetType.ServerNormalBanquet.getValue() == banquetType) {
            return CrossBanquetConfigMgr.isServerNormalBanquet(banquetInfoId);
        } else if (eBanquetType.ServerFeastBanquet.getValue() == banquetType) {
            return CrossBanquetConfigMgr.isServerFeastBanquet(banquetInfoId);
        } else if (eBanquetType.CrossBanquet.getValue() == banquetType) {
            return CrossBanquetConfigMgr.isCrossBanquet(banquetInfoId);
        } else if (eBanquetType.CrossUserBanquet.getValue() == banquetType) {
            return CrossBanquetConfigMgr.isCrossUserBanquet(banquetInfoId);
        }
        return false;
    }

    public static int getUserPost(String partyId, long userId) {
        Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(partyId);
        if (memberMap != null) {
            for (CrossBanquetMember member : new ArrayList<>(memberMap.values())) {
                if (member.getUserId() == userId) {
                    return member.getPos();
                }
            }
        }
        return 0;
    }

    public static Map<Long, CrossPartyRelationship> getPartyRelationshipMap2(long userId) {
        Map<Long, CrossPartyRelationship> userBanquetRelationshipMap = new ConcurrentHashMap<>();
        countRelation(userId, userBanquetRelationshipMap, joinPartyJoinMap, true);
        countRelation(userId, userBanquetRelationshipMap, openPartyJoinMap, false);
        //有在开宴会的在界面上显示宴会
        addRunningPartyToRelationship(userBanquetRelationshipMap, false);
        return userBanquetRelationshipMap;
    }

    private static void addRunningPartyToRelationship(Map<Long, CrossPartyRelationship> userBanquetRelationshipMap, boolean isCross) {
        if (!isCross) {
            for (Map.Entry<Long, CrossPartyRelationship> entry : userBanquetRelationshipMap.entrySet()) {
                Long userId = entry.getKey();
                CrossPartyRelationship relationship = entry.getValue();
                long serverId = relationship.getUserBaseInfo().getServerId();
                Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
                if (dataMap == null) {
                    continue;
                }
                for (CrossBanquetData userBanquetData : dataMap.values()) {
                    if (userBanquetData.getUserId() == userId && !isBanquetOver(userBanquetData.getBanquetId()) && CrossBanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())) {
                        relationship.setBanquetId(userBanquetData.getBanquetId());
                    }
                }
            }
        } else {
            for (CrossBanquetData userBanquetData : CrossBanquetMgr.getRunningBanquet()) {
                if (!CrossBanquetMgr.isBanquetOver(userBanquetData.getBanquetId()) && CrossBanquetConfigMgr.isCrossUserBanquet(userBanquetData.getType())) {
                    if (userBanquetRelationshipMap.containsKey(userBanquetData.getUserId())) {
                        userBanquetRelationshipMap.get(userBanquetData.getUserId()).setBanquetId(userBanquetData.getBanquetId());
                    }
                }
            }
        }
       /* for (CrossBanquetData userBanquetData : partyMap.values()) {
            if (!isBanquetOver(userBanquetData.getBanquetId()) && CrossBanquetConfigMgr.isServerNormalBanquet(userBanquetData.getSchoolType())) {
                if (userBanquetRelationshipMap.containsKey(userBanquetData.getUserId())) {
                    userBanquetRelationshipMap.get(userBanquetData.getUserId()).setBanquetId(userBanquetData.getBanquetId());
                }
            }
        }*/
    }

    private static void countRelation(long userId, Map<Long, CrossPartyRelationship> userBanquetRelationshipMap, Map<Long, List<CrossUserPartyJoin>> joinMap, boolean isJoin) {
        List<CrossUserPartyJoin> joinList = joinMap.get(userId);
        if (joinList == null) {
            return;
        }
        ArrayList<CrossUserPartyJoin> partyJoins = new ArrayList<>(joinList);
        partyJoins.sort((o1, o2) -> Long.compare(o2.getJoinTime(), o1.getJoinTime()));
        for (CrossUserPartyJoin userBanquetJoin : partyJoins) {
            //默认为0，最开始的时候只有本服私人宴会有关系，后来开服争霸私宴也要了
            if (userBanquetJoin.getBanquetType() != 0 && !CrossBanquetConfigMgr.isServerNormalBanquet(userBanquetJoin.getBanquetType()))
                continue;
            countJoinNum(userId, userBanquetRelationshipMap, isJoin, userBanquetJoin);
        }
    }

    //跨服宴会冲榜的私人宴会的互宴信息
    public static Map<Long, CrossPartyRelationship> getBanquetUserRelationshipMap2(long userId, long beginShowTime, long endShowTime) {
        Map<Long, CrossPartyRelationship> userBanquetRelationshipMap = new ConcurrentHashMap<>();
        countRelation(userId, userBanquetRelationshipMap, joinPartyJoinMap, true, beginShowTime, endShowTime);
        countRelation(userId, userBanquetRelationshipMap, openPartyJoinMap, false, beginShowTime, endShowTime);
        //有在开宴会的在界面上显示宴会
        addRunningPartyToRelationship(userBanquetRelationshipMap, true);
        return userBanquetRelationshipMap;
    }

    private static void countRelation(long userId, Map<Long, CrossPartyRelationship> userBanquetRelationshipMap, Map<Long, List<CrossUserPartyJoin>> joinMap, boolean isJoin, long beginShowTime, long endShowTime) {
        List<CrossUserPartyJoin> joinList = joinMap.get(userId);
        if (joinList == null) {
            return;
        }
        ArrayList<CrossUserPartyJoin> partyJoins = new ArrayList<>(joinList);
        partyJoins.sort((o1, o2) -> Long.compare(o2.getJoinTime(), o1.getJoinTime()));
        for (CrossUserPartyJoin userBanquetJoin : partyJoins) {
            if (userBanquetJoin.getJoinTime() / 1000 < beginShowTime || userBanquetJoin.getJoinTime() / 1000 > endShowTime)
                continue;
            //默认为0，最开始的时候只有本服私人宴会有关系，后来开服争霸私宴也要了
            if (userBanquetJoin.getBanquetType() == 0 || !CrossBanquetConfigMgr.isCrossUserBanquet(userBanquetJoin.getBanquetType()))
                continue;
            countJoinNum(userId, userBanquetRelationshipMap, isJoin, userBanquetJoin);
        }
    }

    private static void countJoinNum(long userId, Map<Long, CrossPartyRelationship> userBanquetRelationshipMap, boolean isJoin, CrossUserPartyJoin userBanquetJoin) {
        long relationshipUserId = 0;
        int toOrFrom = 0;//去参加为1，被参加为2,0为无关
        UserBaseInfo userBaseInfo = null;
        if (userBanquetJoin.getUserId1() == userId && isJoin) {
            toOrFrom = 1;
            relationshipUserId = userBanquetJoin.getUserId2();
        } else if (userBanquetJoin.getUserId2() == userId && !isJoin) {
            toOrFrom = 2;
            relationshipUserId = userBanquetJoin.getUserId1();
        } else {
            return;
        }
        userBaseInfo = CrossUserMgr.getUserBaseInfo(relationshipUserId);
        if (userBaseInfo == null) {
            return;
        }
        if (relationshipUserId != 0 && !userBanquetRelationshipMap.containsKey(relationshipUserId)) {
            CrossPartyRelationship info = new CrossPartyRelationship();
            info.setUserId(relationshipUserId);
            info.setTo(0);
            info.setFrom(0);
            info.setUserBaseInfo(userBaseInfo);
            userBanquetRelationshipMap.put(relationshipUserId, info);
        }
        if (toOrFrom != 0) {
            CrossPartyRelationship info = userBanquetRelationshipMap.get(relationshipUserId);
            if (toOrFrom == 1) {
                info.setTo(info.getTo() + 1);
            } else if (toOrFrom == 2) {
                info.setFrom(info.getFrom() + 1);
            }
        }
    }

    public static List<CrossBanquetData> getPartyListByUserId(long serverId, long userId) {
        List<CrossBanquetData> partyList = new ArrayList<>();
        Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
        if (dataMap == null) {
            return partyList;
        }
        for (CrossBanquetData data : new ArrayList<>(dataMap.values())) {
            if (data.getUserId() == userId) {
                partyList.add(data);
            }
        }
        return partyList;
    }

    public static List<Long> getJoinPartyList(String banquetId) {
        List<Long> list = new ArrayList<>();
        Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(banquetId);
        if (memberMap != null) {
            list.addAll(memberMap.keySet());
        }
        return list;
    }


    public static void syncSelfParty(long serverId, long userId, CrossBanquetData nowBanquet) {
        BanquetProto.SyncSelfBanquetMsg.Builder msg = BanquetProto.SyncSelfBanquetMsg.newBuilder();
        List<CrossBanquetData> dataList = CrossPartyMgr.getPartyListByUserId(serverId, userId);
        for (CrossBanquetData info : dataList) {
            if (nowBanquet != null && nowBanquet.getBanquetId().equals(info.getBanquetId()) && isBanquetOver(info.getBanquetId())) {
                msg.addBanquetDataList(CrossBanquetPb.parseBanquetDataTempMsg(info, isSelfJoin(userId, info.getBanquetId()), false, false));
            }
            if (!CrossPartyMgr.isBanquetOver(info.getBanquetId()) && info.getUserId() == userId) {
                msg.addBanquetDataList(CrossBanquetPb.parseBanquetDataTempMsg(info, isSelfJoin(userId, info.getBanquetId()), false, false));
            }
        }
        YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_SELF_SYNC, msg);
        MessageHelper.sendPacket(serverId, userId, message);
    }

    public static void syncPartyMemberList(long serverId, long userId, String partyId) {
        BanquetProto.BanquetMemberInfoResp.Builder respMsg = BanquetProto.BanquetMemberInfoResp.newBuilder();
        if (isBanquetOver(partyId)) {
            respMsg.setRet(GameErrorCode.E_BANQUET_IS_OVER);
            YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_MEMBER_LIST, respMsg);
            MessageHelper.sendPacket(serverId, userId, message);
            return;
        }
        //进入宴会场景
        addBanquetScene(serverId, userId, partyId);
        //分批发送宴会成员，第一次通过协议返回，后面通过同步返回
        CrossBanquetData banquet = partyMap.get(partyId);
        int memNum = 1000;//一次下发多少人
        int length = getBanquetMemberCount(partyId);
        int sendTime = BigDecimal.valueOf(length).divide(BigDecimal.valueOf(memNum), 0, BigDecimal.ROUND_UP).intValue();
        Map<Long, CrossBanquetMember> userBanquetMemberMap = getBanquetMemberMap(partyId, memNum, 1);
        respMsg = CrossBanquetPb.parseBanquetMemberListRespMsg(serverId, userId, banquet, userBanquetMemberMap, length);
        respMsg.setRet(0);
        respMsg.setCount(length);
        YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.U_BANQUET_MEMBER_LIST, respMsg);
        MessageHelper.sendPacket(serverId, userId, message);
        if (sendTime > 1) {
            //    BanquetMgr.syncBanquetMemberTask(player.getUserId(), banquetId, sendTime, memNum, 2);
        }
    }

    private static Map<Long, CrossBanquetMember> getBanquetMemberMap(String partyId, int groupNum, int groupId) {
        List<CrossBanquetMember> memberList = new ArrayList<>();
        if (!isBanquetOver(partyId)) {
            Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(partyId);
            if (memberMap != null) {
                memberList = new ArrayList<>(memberMap.values());
            }
        }
        Map<Long, CrossBanquetMember> groupMemberMap = new ConcurrentHashMap<>();
        memberList.sort((o1, o2) -> {
            if (o1.getPos() == o2.getPos()) {
                return 0;
            }
            if (o1.getPos() >= o2.getPos()) {
                return 1;
            }
            return -1;
        });
        if (groupNum <= 0) {
            for (CrossBanquetMember member : memberList) {
                groupMemberMap.put(member.getUserId(), member);
            }
        } else {
            int startIndex = groupNum * (groupId - 1);
            for (int i = 0; i < groupNum; i++) {
                if (memberList.size() > startIndex + i) {
                    CrossBanquetMember member = memberList.get(startIndex + i);
                    groupMemberMap.put(member.getUserId(), member);
                }
            }
        }
        return groupMemberMap;
    }

    private static int getBanquetMemberCount(String partyId) {
        Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(partyId);
        if (memberMap == null) {
            return 0;
        }
        return memberMap.size();
    }

    private static void addBanquetScene(long serverId, long userId, String partyId) {
        CrossBanquetData data = partyMap.get(partyId);
        if (data != null) {
            data.addSceneUser(serverId, userId);
        }
    }

    public static int leaveParty(String banquetId, long serverId, long userId) {
        if (partyMap.get(banquetId) != null) {
            partyMap.get(banquetId).removeSceneUser(serverId, userId);
        }
        return 0;
    }

    //把结束的宴会移除内存
    private static void clearBanquet() {
        for (CrossBanquetData info : new ArrayList<>(partyMap.values())) {
            //大于3小时的移除掉
            if (System.currentTimeMillis() - info.getOverTime() > 3 * 60 * 60 * 1000 && info.getOp() == DataStatus.None && info.isSendReward()) {
                partyMap.remove(info.getBanquetId());
                removeServerPartyMap(info);
                partyMemberMap.remove(info.getBanquetId());
            }
        }
    }

    private static void removeServerPartyMap(CrossBanquetData info) {
        long serverId = (long) info.getServerId();
        synchronized (serverPartyMap) {
            Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
            if (dataMap != null) {
                dataMap.remove(info.getBanquetId());
            }
        }
    }

    //删除过期的参加宴会记录，本服诗人宴会
    private static void removeExpireJoinRecord() {
        long expireTime = System.currentTimeMillis() - (long) GameConfig.BANQUET_RELATIONSHIP_EXPIRE_TIME * 24 * 60 * 60 * 1000;
        synchronized (partyJoinMap) {
            for (List<CrossUserPartyJoin> userBanquetJoinList : new ArrayList<>(partyJoinMap.values())) {
                Iterator<CrossUserPartyJoin> iterator = userBanquetJoinList.iterator();
                while (iterator.hasNext()) {
                    CrossUserPartyJoin info = iterator.next();
                    if (info.getJoinTime() < expireTime) {
                        iterator.remove();//使用迭代器的删除方法删除
                    }
                }
            }
        }
        removeJoinPartyMap();
    }

    private static void removeJoinPartyMap() {
        long expireTime = System.currentTimeMillis() - (long) GameConfig.BANQUET_RELATIONSHIP_EXPIRE_TIME * 24 * 60 * 60 * 1000;
        synchronized (joinPartyJoinMap) {
            for (List<CrossUserPartyJoin> userBanquetJoinList : new ArrayList<>(joinPartyJoinMap.values())) {
                Iterator<CrossUserPartyJoin> iterator = userBanquetJoinList.iterator();
                while (iterator.hasNext()) {
                    CrossUserPartyJoin info = iterator.next();
                    if (info.getJoinTime() < expireTime) {
                        iterator.remove();//使用迭代器的删除方法删除
                    }
                }
            }
        }
        synchronized (openPartyJoinMap) {
            for (List<CrossUserPartyJoin> userBanquetJoinList : new ArrayList<>(openPartyJoinMap.values())) {
                Iterator<CrossUserPartyJoin> iterator = userBanquetJoinList.iterator();
                while (iterator.hasNext()) {
                    CrossUserPartyJoin info = iterator.next();
                    if (info.getJoinTime() < expireTime) {
                        iterator.remove();//使用迭代器的删除方法删除
                    }
                }
            }
        }
    }

    public static Map<String, CrossBanquetData> getOverPartyMap(long serverId, long userId) {
        Map<String, CrossBanquetData> dataMap = new HashMap<>();
        Map<String, CrossBanquetData> banquetDataMap = serverPartyMap.get(serverId);
        if (banquetDataMap != null) {
            for (CrossBanquetData party : new ArrayList<>(banquetDataMap.values())) {
                if (isBanquetOver(party.getBanquetId()) && party.getUserId() == userId && !party.isSendReward()) {
                    dataMap.put(party.getBanquetId(), party);
                }
            }
        }
        return dataMap;
    }

    public static void fullRobotSeat(CrossBanquetData banquet) {
        BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(banquet.getType());
        int needAdd = banquetInfo.getSeat() - banquet.getUserCount();
        for (int i = 0; i < needAdd; i++) {
            robotsJoinBanquet(banquet.getUserCount() + 1, banquet);
        }
    }

    private static void robotsJoinBanquet(int i, CrossBanquetData banquet) {
        synchronized (banquet) {
            BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(banquet.getType());
            if (banquetInfo == null) {
                return;
            }
            if ("0".equals(banquetInfo.getRobots())) {
                return;
            }
            List<Integer> robotList = StringUtils.stringToIntegerList(banquetInfo.getRobots(), "=");
            BanquetGiftInfo banquetGiftInfo = CrossBanquetConfigMgr.getBanquetGiftInfo(banquet.getType(), robotList.get(1));
            if (banquetGiftInfo == null) {
                return;
            }
            if (banquet.getUserCount() >= banquetInfo.getSeat() && banquetInfo.getSeat() != 0) {
                return;
            }
            Map<Long, CrossBanquetMember> memberMap = getPartyMemberMap(banquet.getBanquetId());
            CrossBanquetMember userBanquetMember = new CrossBanquetMember();
            userBanquetMember.setBanquetId(banquet.getBanquetId());
            userBanquetMember.setUserId(i);
            userBanquetMember.setGiftId(robotList.get(1));
            userBanquetMember.setRobot(true);
            userBanquetMember.setRobotProcessId(i);
            userBanquetMember.setRobotId(robotList.get(0));
            userBanquetMember.setPos(memberMap.size() + 1);
            userBanquetMember.setPopularity(0);
            userBanquetMember.setIntegral(0);
            userBanquetMember.setUserBaseInfo(initRobotUserInfo());
            userBanquetMember.setJoinTime(System.currentTimeMillis());
            if (!"0".equals(banquetGiftInfo.getJoinScore())) {
                //随礼的奖励值加上头衔加成千分比
                Property joinScore = PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinScore());
                long popularity = joinScore.getCountByGoodsId(GameConfig.BANQUET_POPULARITY).longValue();
                long integral = joinScore.getCountByGoodsId(GameConfig.BANQUET_INTEGRAL).longValue();
                userBanquetMember.setPopularity(popularity);
                userBanquetMember.setIntegral(integral);
                if (CrossBanquetConfigMgr.isServerNormalBanquet(banquet.getType())) {
                    //宴会加上人气和积分
                    banquet.setPopularity(banquet.getPopularity() + popularity);
                    banquet.setIntegral(banquet.getIntegral() + integral);
                }
            }
            userBanquetMember.setInsertOption();
            memberMap.put(userBanquetMember.getUserId(), userBanquetMember);

            banquet.setUserCount(memberMap.size());

            //人满了直接发满员幸运奖励
            if (memberMap.size() == banquetInfo.getSeat()) {
                sendLuckUserReward(banquetInfo, banquet, memberMap);
            }
            syncBanquetUser(banquet, userBanquetMember);
        }
    }

    public static void sendBanquetUserRecord(CrossBanquetData crossBanquetData) {
        UserBanquetData data = new UserBanquetData();
        data.setBanquetId(crossBanquetData.getBanquetId());
        data.setUserId(crossBanquetData.getUserId());
        data.setType(crossBanquetData.getType());
        data.setInvitationId(crossBanquetData.getInvitationId());
        data.setOpenTime(crossBanquetData.getOpenTime());
        data.setOverTime(crossBanquetData.getOverTime());
        data.setSendReward(crossBanquetData.isSendReward());
        data.setPopularity(crossBanquetData.getPopularity());
        data.setIntegral(crossBanquetData.getIntegral());
        data.setUserCount(crossBanquetData.getUserCount());
        data.setInvitationInfo(crossBanquetData.getInvitationInfo());
        data.setEndReward(crossBanquetData.getEndReward());
        data.setUserBaseInfo(crossBanquetData.getUserBaseInfo());
        Map<Long, CrossBanquetMember> memberMap = crossBanquetData.getMemberMap();
        Map<Long, UserBanquetMember> map = new HashMap<>();
        if (CrossBanquetConfigMgr.isServerNormalBanquet(crossBanquetData.getType())) {
            for (CrossBanquetMember member : memberMap.values()) {
                try {
                    UserBanquetMember banquetMember = new UserBanquetMember();
                    banquetMember.setBanquetId(member.getBanquetId());
                    banquetMember.setUserId(member.getUserId());
                    banquetMember.setRobot(member.isRobot());
                    banquetMember.setRobotProcessId(member.getRobotProcessId());
                    banquetMember.setRobotId(member.getRobotId());
                    banquetMember.setGiftId(member.getGiftId());
                    banquetMember.setPopularity(member.getPopularity());
                    banquetMember.setIntegral(member.getIntegral());
                    banquetMember.setPos(member.getPos());
                    banquetMember.setUserBaseInfo(member.getUserBaseInfo());
                    map.put(banquetMember.getUserId(), banquetMember);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        data.setUserBanquetMemberMap(map);

        UserBanquetRecord userBanquetRecord = new UserBanquetRecord();
        userBanquetRecord.setBanquetId(crossBanquetData.getBanquetId());
        userBanquetRecord.setType(crossBanquetData.getType());
        userBanquetRecord.setUserId(crossBanquetData.getUserId());
        crossBanquetData.setMemberMap(getPartyMemberMap(crossBanquetData.getBanquetId()));
        userBanquetRecord.setRecord(JSON.toJSONString(data));
        userBanquetRecord.setOpenTime(crossBanquetData.getOpenTime());
        userBanquetRecord.setOverTime(crossBanquetData.getOverTime());
        userBanquetRecord.setMemberCount(crossBanquetData.getUserCount());

        CrossBanquetProto.SendCrossUserBanquetRecordMsg.Builder respMsg = CrossBanquetProto.SendCrossUserBanquetRecordMsg.newBuilder();
        respMsg.setBanquetId(userBanquetRecord.getBanquetId());
        respMsg.setType(userBanquetRecord.getType());
        respMsg.setUserId(userBanquetRecord.getUserId());
        respMsg.setRecord(userBanquetRecord.getRecord());
        respMsg.setOpenTime(userBanquetRecord.getOpenTime());
        respMsg.setOverTime(userBanquetRecord.getOverTime());
        respMsg.setMemberCount(userBanquetRecord.getMemberCount());

        YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.S_CROSS_PARTY_RECORD, respMsg);
        MessageHelper.sendPacket(crossBanquetData.getServerId(), crossBanquetData.getUserId(), pbMsg);
    }


    public static CrossBanquetData getParty(String banquetId) {
        return partyMap.get(banquetId);
    }

    public static boolean isSelfJoin(long userId, String banquetId) {
        if (partyMemberMap.containsKey(banquetId) && partyMemberMap.get(banquetId).containsKey(userId)) {
            return true;
        }
        return false;
    }

    public static CrossBanquetData getUserParty(long searchServerId, long searchUserId) {
        if (searchServerId == 0) {
            List<CrossBanquetData> banquetList = new ArrayList<>(partyMap.values());
            for (CrossBanquetData data : banquetList) {
                if (!isBanquetOver(data.getBanquetId()) && data.getUserId() == searchUserId && isBanquetType(data.getType(), eBanquetType.ServerNormalBanquet.getValue())) {
                    return data;
                }
            }
        } else {
            Map<String, CrossBanquetData> dataMap = serverPartyMap.get(searchServerId);
            if (dataMap == null) {
                return null;
            }
            List<CrossBanquetData> banquetList = new ArrayList<>(dataMap.values());
            for (CrossBanquetData data : banquetList) {
                if (!isBanquetOver(data.getBanquetId()) && data.getUserId() == searchUserId && isBanquetType(data.getType(), eBanquetType.ServerNormalBanquet.getValue())) {
                    return data;
                }
            }
        }
        return null;
    }

    public static void syncCrossFeastParty() {
        Map<Long, Map<String, CrossBanquetData>> serverFeastPartyMap = new HashMap<>();
        for (CrossBanquetData data : new ArrayList<>(partyMap.values())) {
            if (isBanquetOver(data.getBanquetId())) {
                continue;
            }
            if (!CrossBanquetConfigMgr.isServerFeastBanquet(data.getType())) {
                continue;
            }
            List<Long> feastPartyServerList = CrossMarriageGroupMgr.getFeastPartyServerList(data.getServerId());
            for (Long serverId : feastPartyServerList) {
                if (!serverFeastPartyMap.containsKey(serverId)) {
                    serverFeastPartyMap.put(serverId, new HashMap<>());
                }
                serverFeastPartyMap.get(serverId).put(data.getBanquetId(), data);
            }
        }
        syncCrossFeastPartyMsg(serverFeastPartyMap);
    }

    private static void syncCrossFeastParty(long serverId) {
        Map<Long, Map<String, CrossBanquetData>> serverFeastPartyMap = new HashMap<>();
        List<Long> feastPartyServerList = CrossMarriageGroupMgr.getFeastPartyServerList(serverId);
        for (CrossBanquetData data : new ArrayList<>(partyMap.values())) {
            if (isBanquetOver(data.getBanquetId())) {
                continue;
            }
            if (!CrossBanquetConfigMgr.isServerFeastBanquet(data.getType())) {
                continue;
            }
            if (!feastPartyServerList.contains((long) data.getServerId())) {
                continue;
            }
            for (Long id : feastPartyServerList) {
                if (!serverFeastPartyMap.containsKey(id)) {
                    serverFeastPartyMap.put(id, new HashMap<>());
                }
                serverFeastPartyMap.get(id).put(data.getBanquetId(), data);
            }
        }
        syncCrossFeastPartyMsg(serverFeastPartyMap);
    }

    private static void syncCrossFeastPartyMsg(Map<Long, Map<String, CrossBanquetData>> serverFeastPartyMap) {
        for (Map.Entry<Long, Map<String, CrossBanquetData>> entry : serverFeastPartyMap.entrySet()) {
            Long serverId = entry.getKey();
            Map<String, CrossBanquetData> dataMap = entry.getValue();
            BanquetProto.CrossFeastPartySyncMsg.Builder syncMsg = BanquetProto.CrossFeastPartySyncMsg.newBuilder();
            for (CrossBanquetData data : dataMap.values()) {
                BanquetProto.CrossFEastPartyTempMsg.Builder msg = BanquetProto.CrossFEastPartyTempMsg.newBuilder();
                msg.setBanquetId(data.getBanquetId());
                msg.setOverTime(data.getOverTime());
                msg.setUserCount(data.getUserCount());
                syncMsg.addMsg(msg);
            }
            YanQuMessage message = YanQuMessageUtils.buildMessage(Protocol.S_CROSS_PARTY_FEAST_SYNC, syncMsg);
            MessageHelper.sendPacket(serverId, 0, message);
        }
    }

    public static Map<Long, CrossPartyRelationship> getPartyRelationship(long userId, int partyType, long beginTime) {
        Map<Long, CrossPartyRelationship> relationshipMap = new ConcurrentHashMap<>();
        Map<Long, List<CrossPartyRelationData>> dataMap = partyRelationshipMap.get(partyType);
        if (dataMap != null) {
            List<CrossPartyRelationData> relationDataMap = dataMap.get(userId);
            if (relationDataMap != null) {
                for (CrossPartyRelationData entry : relationDataMap) {
                    CrossPartyRelationship crossPartyRelationship = new CrossPartyRelationship();
                    long otherUser;
                    if (entry.getUserId1() == userId) {
                        otherUser = entry.getUserId2();
                    } else {
                        otherUser = entry.getUserId1();
                    }
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(otherUser);
                    if (userBaseInfo == null) {
                        continue;
                    }
                    crossPartyRelationship.setUserBaseInfo(userBaseInfo);
                    crossPartyRelationship.setUserId(otherUser);
                    CrossPartyRelationData data = entry;
                    if (data.getLastJoinTime() < beginTime) {
                        continue;
                    }
                    if (data.getUserId1() == userId) {
                        crossPartyRelationship.setTo(data.getJoinTimes1());
                        crossPartyRelationship.setFrom(data.getJoinTimes2());
                    } else {
                        crossPartyRelationship.setTo(data.getJoinTimes2());
                        crossPartyRelationship.setFrom(data.getJoinTimes1());
                    }
                    crossPartyRelationship.setLastJoinTime(data.getLastJoinTime());
                    relationshipMap.put(otherUser, crossPartyRelationship);
                }
            }
        }
        return relationshipMap;
    }

    public static Map<Long, List<CrossPartyRelationship>> getAllPartyRelationship(int partyType, long beginTime) {
        Map<Long, List<CrossPartyRelationship>> relationshipMap = new ConcurrentHashMap<>();
        Map<Long, List<CrossPartyRelationData>> dataMap = partyRelationshipMap.get(partyType);
        if (dataMap != null) {
            for (Map.Entry<Long, List<CrossPartyRelationData>> entry : dataMap.entrySet()) {
                Long myUserId = entry.getKey();
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(myUserId);
                if (userBaseInfo == null) {
                    continue;
                }
                long serverId = userBaseInfo.getServerId();
                if (!relationshipMap.containsKey(serverId)) {
                    relationshipMap.put(serverId, new ArrayList<>());
                }
                List<CrossPartyRelationship> list = relationshipMap.get(serverId);
                for (CrossPartyRelationData data : entry.getValue()) {
                    CrossPartyRelationship crossPartyRelationship = new CrossPartyRelationship();
                    long otherUser;
                    if (data.getUserId1() == myUserId) {
                        otherUser = data.getUserId2();
                    } else {
                        otherUser = data.getUserId1();
                    }
                    UserBaseInfo otherUserInfo = CrossUserMgr.getUserBaseInfo(otherUser);
                    if (otherUserInfo == null) {
                        continue;
                    }
                    crossPartyRelationship.setUserBaseInfo(otherUserInfo);
                    crossPartyRelationship.setUserId(otherUser);
                    if (data.getLastJoinTime() < beginTime) {
                        continue;
                    }
                    if (data.getUserId1() == myUserId) {
                        crossPartyRelationship.setTo(data.getJoinTimes1());
                        crossPartyRelationship.setFrom(data.getJoinTimes2());
                    } else {
                        crossPartyRelationship.setTo(data.getJoinTimes2());
                        crossPartyRelationship.setFrom(data.getJoinTimes1());
                    }
                    crossPartyRelationship.setLastJoinTime(data.getLastJoinTime());
                    crossPartyRelationship.setMyUserId(myUserId);
                    list.add(crossPartyRelationship);
                }
            }
        }
        return relationshipMap;
    }

    public static void relationshipAck(long serverId) {
        ackRelationshipMap.put(serverId, 1);
    }

    public static void enterNextFeastParty(long serverId, long userId, String curId, int pageNum, int pageSize) {
        CrossBanquetData nextParty = null;
        List<CrossBanquetData> partyList = getBanquetFeast(CrossMarriageGroupMgr.getFeastPartyServerList(serverId));

        for (CrossBanquetData data : partyList) {
            if (Objects.equals(data.getBanquetId(), curId)) {
                continue;
            }
            Map<Long, CrossBanquetMember> memberMap = partyMemberMap.get(data.getBanquetId());
            if (!memberMap.containsKey(userId)) {
                nextParty = data;
                break;
            }
        }
        CrossBanquetProto.BanquetEnterNextResp.Builder resp = CrossBanquetProto.BanquetEnterNextResp.newBuilder();
        if (nextParty == null) {
            resp.setRet(GameErrorCode.E_BANQUET_NO_NEXT);
        } else {
            resp.setRet(0);
            resp.setCount(nextParty.getUserCount());
            BanquetProto.BanquetTemp.Builder banquetDataTempMsg = CrossBanquetPb.parseBanquetDataTempMsg(nextParty, false, false, false);
            resp.setBanquetInfo(banquetDataTempMsg);
            Map<Long, CrossBanquetMember> userBanquetMemberMap = getBanquetMemberMap(nextParty.getBanquetId(), 1000, 1);
            for (CrossBanquetMember member : userBanquetMemberMap.values()) {
                resp.addMemberList(CrossBanquetPb.parseBanquetMemberTempMsg(member));
            }
        }
        YanQuMessage message = YanQuMessageUtils.buildMessage(ClientProtocol.U_BANQUET_ENTER_NEXT, resp);
        MessageHelper.sendPacket(serverId, userId, message);
    }


    @Override
    public boolean reloadData() throws Exception {
        partyMap = CrossPartyBusiness.getCrossPartyMap();
        initCrossPartyMember();
        long beginTime = System.currentTimeMillis() - 30 * 1000L * 24 * 3600;
        List<CrossPartyRelationData> relationDataList = new CrossPartyRelationDaoImpl().getCrossPartyRelationData(beginTime);
        if (relationDataList.isEmpty()) {
            partyJoinMap = CrossPartyBusiness.getCrossPartyJoinMap();
        }
        initServerPArtyMap();
        initJoinMap(relationDataList);
        return true;
    }

    private void initJoinMap(List<CrossPartyRelationData> relationDataList) {
        for (CrossPartyRelationData data : relationDataList) {
            long userId1 = data.getUserId1();
            long userId2 = data.getUserId2();
            int partyType = data.getPartyType();
            Map<Long, List<CrossPartyRelationData>> mapMap = partyRelationshipMap.get(partyType);
            if (mapMap == null) {
                mapMap = new ConcurrentHashMap<>();
                partyRelationshipMap.put(partyType, mapMap);
            }
            addRelationDataToMap(data, userId1, userId2, mapMap);
            addRelationDataToMap(data, userId2, userId1, mapMap);
        }
        addOldRelationData();
    }

    /**
     * 这是为了迭代数据用的 执行过一次就删了吧
     * 港澳台3.3上线 后面要删除
     */
    private void addOldRelationData() {
        if (!partyRelationshipMap.isEmpty()) {
            return;
        }
        for (List<CrossUserPartyJoin> joinList : partyJoinMap.values()) {
            for (CrossUserPartyJoin join : joinList) {
                addPartyRelationship(join.getUserId2(), join.getUserId1(), null, null, join.getBanquetType(), Long.MAX_VALUE);
            }
        }
        partyJoinMap.clear();
        joinPartyJoinMap.clear();
        openPartyJoinMap.clear();
    }

    private void addRelationDataToMap(CrossPartyRelationData data, long userId1, long userId2, Map<Long, List<CrossPartyRelationData>> mapMap) {
        List<CrossPartyRelationData> dataMap = mapMap.get(userId1);
        if (dataMap == null) {
            dataMap = new ArrayList<>();
            mapMap.put(userId1, dataMap);
        }
        dataMap.add(data);
    }

    private static void addToOpenPartyJoinMap(CrossUserPartyJoin join) {
        long userId = join.getUserId2();
        synchronized (openPartyJoinMap) {
            List<CrossUserPartyJoin> list = openPartyJoinMap.get(userId);
            if (list == null) {
                list = new ArrayList<>();
                openPartyJoinMap.put(userId, list);
            }
            list.add(join);
        }
    }

    private static void addToJoinPartyJoinMap(CrossUserPartyJoin join) {
        long userId = join.getUserId1();
        synchronized (joinPartyJoinMap) {
            List<CrossUserPartyJoin> list = joinPartyJoinMap.get(userId);
            if (list == null) {
                list = new ArrayList<>();
                joinPartyJoinMap.put(userId, list);
            }
            list.add(join);
        }
    }

    private void initServerPArtyMap() {
        Map<Long, Map<String, CrossBanquetData>> tempMap = new ConcurrentHashMap<>();
        for (CrossBanquetData data : partyMap.values()) {
            long serverId = (long) data.getServerId();
            if (!tempMap.containsKey(serverId)) {
                tempMap.put(serverId, new ConcurrentHashMap<>());
            }
            tempMap.get(serverId).put(data.getBanquetId(), data);
        }
        serverPartyMap = tempMap;
    }

    private static void initCrossPartyMember() {
        for (CrossBanquetData data : partyMap.values()) {
            //本服盛宴不读取
            if (!CrossBanquetConfigMgr.isServerNormalBanquet(data.getType()) && isBanquetOver(data.getBanquetId())) {
                continue;
            }
            Map<Long, CrossBanquetMember> userMap = CrossPartyBusiness.getCrossPartyMapByPartyId(data.getBanquetId());
            if (userMap != null) {
                for (CrossBanquetMember member : userMap.values()) {
                    resetUserBaseInfo(member);
                }
            }
            partyMemberMap.put(data.getBanquetId(), userMap);
            //如果是跨服私人宴会要把人放上去，生成记录时候要用
            data.setMemberMap(userMap);
            data.setUserCount(userMap.size());
        }
    }

    public static void robotsJoin() {
        List<CrossBanquetData> banquetList = new ArrayList<>(partyMap.values());
        for (CrossBanquetData data : banquetList) {
            synchronized (data) {
                if (CrossBanquetConfigMgr.isServerFeastBanquet(data.getType()) && !isBanquetOver(data.getBanquetId())) {
                        /*if(data.getUserCount() < 500){
                            int addCount = 20;
                            for(int i=0;i<addCount;i++){
                                robotsJoinBanquetTemp(data);
                            }
                        }*/
                }
                if (CrossBanquetConfigMgr.isServerNormalBanquet(data.getType()) && !isBanquetOver(data.getBanquetId())) {
                    int processId = getRobotsConditionProcessId(data);
                    if (processId != 0) {
                        robotsJoinBanquet(processId, data);
                    }
                }
            }
        }
    }

    //获取是否要触发机器人
    private static int getRobotsConditionProcessId(CrossBanquetData userBanquetData) {
        synchronized (userBanquetData) {
            BanquetInfo banquetInfo = CrossBanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
            Map<Integer, List<Integer>> processMap = CrossBanquetConfigMgr.getRobotCondtion();
            Map<Long, CrossBanquetMember> memberMap = getPartyMemberMap(userBanquetData.getBanquetId());
            for (Integer processId : processMap.keySet()) {
                //是否有机器人了
                boolean robotFlag = false;
                List<Integer> processList = processMap.get(processId);
                long timePass = BigInteger.valueOf(userBanquetData.getOverTime() - userBanquetData.getOpenTime()).multiply(BigInteger.valueOf(processList.get(0))).divide(BigInteger.valueOf(100)).longValue();
                long timeProcess = timePass + userBanquetData.getOpenTime();
                if (System.currentTimeMillis() < timeProcess) {
                    continue;
                }
                long seatPass = BigDecimal.valueOf(banquetInfo.getSeat()).multiply(BigDecimal.valueOf(processList.get(1))).divide(BigDecimal.valueOf(100), 0, BigDecimal.ROUND_UP).longValue();
                if (memberMap.size() >= seatPass) {
                    continue;
                }
                for (CrossBanquetMember member : memberMap.values()) {
                    if (member.isRobot() && processId == member.getRobotProcessId()) {
                        robotFlag = true;
                        break;
                    }
                }
                if (!robotFlag) {
                    return processId;
                }
            }
            return 0;
        }
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for (CrossBanquetData party : new ArrayList<>(partyMap.values())) {
            if (party.isInsertOption()) {
                CrossPartyBusiness.addCrossParty(party);
            } else if (party.isUpdateOption()) {
                CrossPartyBusiness.updateCrossParty(party);
            }
        }
        for (Map<Long, CrossBanquetMember> memberMap : new ArrayList<>(partyMemberMap.values())) {
            for (CrossBanquetMember member : new ArrayList<>(memberMap.values())) {
                resetUserBaseInfo(member);
                if (member.isInsertOption()) {
                    CrossPartyBusiness.addCrossPartyMember(member);
                } else if (member.isUpdateOption()) {
                    CrossPartyBusiness.updateCrossPartyMember(member);
                }
            }
        }
        for (List<CrossUserPartyJoin> joinList : new ArrayList<>(partyJoinMap.values())) {
            for (CrossUserPartyJoin join : new ArrayList<>(joinList)) {
                if (join.isInsertOption()) {
                    CrossPartyBusiness.addCrossPartyJoin(join);
                }
            }
        }
        clearBanquet();
        //removeExpireJoinRecord();
        syncRelationship();
        return true;
    }

    private void syncRelationship() {
        boolean allsync = true;
        if (ackRelationshipMap.size() > 0) {
            for (Integer value : ackRelationshipMap.values()) {
                if (value == 0) {
                    allsync = false;
                }
            }
        } else {
            allsync = false;
        }
        if (allsync) {
            return;
        }

        Map<Long, List<CrossPartyRelationship>> CrossRecordMap = CrossPartyMgr.getAllPartyRelationship(2, System.currentTimeMillis() - 7 * 24L * 3600 * 1000);
        Map<Long, List<CrossPartyRelationship>> recordMap = CrossPartyMgr.getAllPartyRelationship(1, 0);

        Map<Long, List<BanquetProto.BanquetRelationshipDataMsg>> msgMap = new HashMap<>();

        for (Map.Entry<Long, List<CrossPartyRelationship>> entry : recordMap.entrySet()) {
            Long serverId = entry.getKey();
            Integer value = ackRelationshipMap.get(serverId);
            if (Objects.equals(value, 1)) {
                continue;
            }
            if (!msgMap.containsKey(serverId)) {
                msgMap.put(serverId, new ArrayList<>());
            }
            List<BanquetProto.BanquetRelationshipDataMsg> list = msgMap.get(serverId);
            for (CrossPartyRelationship data : entry.getValue()) {
                BanquetProto.BanquetRelationshipDataMsg.Builder msg = BanquetProto.BanquetRelationshipDataMsg.newBuilder();
                msg.setMyTimes(data.getTo());
                msg.setOtherUserId(data.getUserId());
                msg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(data.getUserBaseInfo()));
                msg.setOtherTimes(data.getFrom());
                msg.setLastJoinTime(data.getLastJoinTime());
                msg.setType(1);
                msg.setMyUserId(data.getMyUserId());
                list.add(msg.build());
            }
        }

        for (Map.Entry<Long, List<CrossPartyRelationship>> entry : CrossRecordMap.entrySet()) {
            Long serverId = entry.getKey();
            if (!msgMap.containsKey(serverId)) {
                msgMap.put(serverId, new ArrayList<>());
            }
            List<BanquetProto.BanquetRelationshipDataMsg> list = msgMap.get(serverId);
            for (CrossPartyRelationship data : entry.getValue()) {
                BanquetProto.BanquetRelationshipDataMsg.Builder msg = BanquetProto.BanquetRelationshipDataMsg.newBuilder();
                msg.setMyTimes(data.getTo());
                msg.setOtherUserId(data.getUserId());
                msg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(data.getUserBaseInfo()));
                msg.setOtherTimes(data.getFrom());
                msg.setLastJoinTime(data.getLastJoinTime());
                msg.setType(2);
                msg.setMyUserId(data.getMyUserId());
                list.add(msg.build());
            }
        }
        for (Map.Entry<Long, List<BanquetProto.BanquetRelationshipDataMsg>> entry : msgMap.entrySet()) {
            BanquetProto.CrossBanquetRelationshipRespMsg.Builder resp = BanquetProto.CrossBanquetRelationshipRespMsg.newBuilder();

            Long serverId = entry.getKey();
            List<BanquetProto.BanquetRelationshipDataMsg> value = entry.getValue();
            resp.addAllData(value);
            ackRelationshipMap.put(serverId, 0);
            YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_RELATIONSHIP_INIT_SYNC, resp);
            MessageHelper.sendPacket(serverId, 0, message);
        }
    }

    private static void resetUserBaseInfo(CrossBanquetMember member) {
        if (!member.isRobot()) {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(member.getUserId());
            if (userBaseInfo != null) {
                member.setUserBaseInfo(userBaseInfo);
            } else {
                CrossUserMgr.updateUserBaseInfo(member.getUserId(), member.getUserBaseInfo());
            }
        }
    }

    public void saveRelationData() {
        List<CrossPartyRelationData> tempList;
        synchronized (needUpdateRelationDataLSet) {
            tempList = new ArrayList<>(needUpdateRelationDataLSet);
            needUpdateRelationDataLSet.clear();
        }
        for (CrossPartyRelationData data : tempList) {
            if (data.isInsertOption()) {
                new CrossPartyRelationDaoImpl().add(data);
            } else if (data.isUpdateOption()) {
                new CrossPartyRelationDaoImpl().update(data);
            }
        }
    }

    public static void changeGroup() {
        if (partyMap == null) {
            // 没有的话就不刷了，分组跨服没宴会了
            return;
        }
        synchronized (partyMap) {
            ArrayList<CrossBanquetData> partyList = new ArrayList<>(partyMap.values());
            for (CrossBanquetData party : partyList) {
                if (!CrossBanquetConfigMgr.isServerNormalBanquet(party.getType())) {
                    continue;
                }
                if (isBanquetOver(party.getBanquetId())) {
                    continue;
                }
                List<Integer> serverList = party.getServerList();
                List<Long> partyServerList = CrossMarriageGroupMgr.getPartyServerList(party.getServerId());
                List<Integer> tempList = new ArrayList<>();
                for (Long serverId : partyServerList) {
                    tempList.add(serverId.intValue());
                }
                if (ListHelper.integerListCompare(serverList, tempList)) {
                    continue;
                }
                fullRobotSeat(party);
                getLogger().warn("{} change group, party {} full robots", party.getServerId(), party.getBanquetId());
            }
        }
    }

    public static CrossBanquetData getPartyByUserIdAndType(long serverId, long userId, int type) {
        Map<String, CrossBanquetData> dataMap = serverPartyMap.get(serverId);
        if (dataMap == null) {
            return null;
        }
        for (CrossBanquetData data : new ArrayList<>(dataMap.values())) {
            if (data.getUserId() == userId && data.getType() == type && !isBanquetOver(data.getBanquetId())) {
                return data;
            }
        }
        return null;
    }

    public static boolean updatePartySetting(long serverId, long userId, int type, String giftTypeAccept, String banquetId, String message1) {
        CrossBanquetData crossBanquetData = null;
        if (StringUtils.isNullOrEmpty(banquetId)) {
            crossBanquetData = getPartyByUserIdAndType(serverId, userId, type);
        } else {
            crossBanquetData = getParty(banquetId);
        }

        if (null == crossBanquetData) {
            return false;
        }
        if (crossBanquetData.getType() != type || crossBanquetData.getUserId() != userId) {
            return false;
        }
        if (!isBanquetOver(banquetId)) {
            crossBanquetData.setGiftTypeAccept(giftTypeAccept);
            crossBanquetData.setMessage(message1);
        }

        BanquetProto.UpdateBanquetSettingCrossRespMsg.Builder resp = BanquetProto.UpdateBanquetSettingCrossRespMsg.newBuilder();
        resp.setType(type);
        resp.setGiftTypeAccept(giftTypeAccept);
        resp.setBanquetId(crossBanquetData.getBanquetId());
        resp.setMessage(message1);
        YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_BANQUET_CROSS_SETTING_UPDATE, resp);
        MessageHelper.sendPacket(serverId, userId, message);
        return true;
    }

}
